const Parse = require('parse/node');

// Initialize Parse
Parse.initialize("NwrNwnQTDLxBoneM8ziHiyJCQ56miSCLEWYpPk4i", "KT0OObN8SpUJ4AklXs4QJwcoYsJPhkvMxvKSAXQe");
Parse.serverURL = 'https://parseapi.back4app.com/';

// 1) answerQuestion - 事务：校验答案→自增score→减unansweredCount→返回isCorrect
Parse.Cloud.define("answerQuestion", async (request) => {
  const { roomId, questionId, optionIndex, username } = request.params;
  const user = request.user;

  if (!user || !roomId || !questionId || optionIndex === undefined || !username) {
    throw new Error('Missing required parameters');
  }

  try {
    // Start transaction
    const result = await Parse.Cloud.useMasterKey(async () => {
      // Get question for validation
      const questionQuery = new Parse.Query("Question");
      const question = await questionQuery.get(questionId, { useMasterKey: true });
      
      if (!question) {
        throw new Error('Question not found');
      }

      const correctAnswer = question.get("answerIndex");
      const isCorrect = optionIndex === correctAnswer;
      const difficulty = question.get("difficulty") || 1;
      
      // Calculate points
      const basePoints = difficulty * 100;
      const pointsEarned = isCorrect ? basePoints : 0;

      // Get room
      const roomQuery = new Parse.Query("Room");
      const room = await roomQuery.get(roomId, { useMasterKey: true });
      
      if (!room) {
        throw new Error('Room not found');
      }

      // Get or create user score
      const userScoreQuery = new Parse.Query("UserScore");
      userScoreQuery.equalTo("roomId", roomId);
      userScoreQuery.equalTo("userId", user.id);
      
      let userScore = await userScoreQuery.first({ useMasterKey: true });
      
      if (!userScore) {
        const UserScore = Parse.Object.extend("UserScore");
        userScore = new UserScore();
        userScore.set("roomId", roomId);
        userScore.set("userId", user.id);
        userScore.set("username", username);
        userScore.set("score", 0);
      }

      // Update user score
      const currentScore = userScore.get("score") || 0;
      userScore.set("score", currentScore + pointsEarned);

      // Update room unanswered count if wrong answer
      if (!isCorrect) {
        const currentUnanswered = room.get("unansweredCount") || 0;
        room.set("unansweredCount", currentUnanswered + 1);
      }

      // Save changes in transaction
      await Parse.Object.saveAll([userScore, room], { useMasterKey: true });

      // Log answer
      const AnswerLog = Parse.Object.extend("AnswerLog");
      const answerLog = new AnswerLog();
      answerLog.set("roomId", roomId);
      answerLog.set("questionId", questionId);
      answerLog.set("userId", user.id);
      answerLog.set("username", username);
      answerLog.set("selectedOption", optionIndex);
      answerLog.set("isCorrect", isCorrect);
      answerLog.set("pointsEarned", pointsEarned);
      answerLog.set("difficulty", difficulty);
      
      await answerLog.save(null, { useMasterKey: true });

      return {
        success: true,
        isCorrect: isCorrect,
        pointsEarned: pointsEarned,
        correctAnswer: correctAnswer,
        newScore: currentScore + pointsEarned
      };
    });

    return result;

  } catch (error) {
    console.error("Error in answerQuestion:", error);
    return {
      success: false,
      error: error.message
    };
  }
});

// 2) matchPoolCron - 每1s运行，把MatchPool内未满6人合并→新建Room→推Parse Push
let matchPoolInterval = null;

Parse.Cloud.define("startMatchPoolCron", async (request) => {
  if (matchPoolInterval) {
    return { success: false, message: "Match pool cron already running" };
  }

  matchPoolInterval = setInterval(async () => {
    try {
      await processMatchPool();
    } catch (error) {
      console.error("Error in match pool cron:", error);
    }
  }, 1000);

  return { success: true, message: "Match pool cron started" };
});

Parse.Cloud.define("stopMatchPoolCron", async (request) => {
  if (matchPoolInterval) {
    clearInterval(matchPoolInterval);
    matchPoolInterval = null;
    return { success: true, message: "Match pool cron stopped" };
  }
  return { success: false, message: "Match pool cron not running" };
});

async function processMatchPool() {
  try {
    // Get all players in match pool grouped by difficulty
    const matchPoolQuery = new Parse.Query("MatchPool");
    const matchPoolEntries = await matchPoolQuery.find({ useMasterKey: true });

    // Group by difficulty
    const playersByDifficulty = {};
    
    for (const entry of matchPoolEntries) {
      const difficulty = entry.get("difficulty") || 1;
      const userId = entry.get("userId");
      
      if (!playersByDifficulty[difficulty]) {
        playersByDifficulty[difficulty] = [];
      }
      
      // Check if user is not already in a room
      const userRoomQuery = new Parse.Query("Room");
      userRoomQuery.equalTo("users", entry.get("user"));
      const existingRoom = await userRoomQuery.first({ useMasterKey: true });
      
      if (!existingRoom) {
        playersByDifficulty[difficulty].push({
          entry: entry,
          user: entry.get("user"),
          username: entry.get("username")
        });
      }
    }

    // Process each difficulty level
    for (const difficulty in playersByDifficulty) {
      const players = playersByDifficulty[difficulty];
      
      // Group players into rooms of max 6
      while (players.length >= 2) { // Minimum 2 players to start a room
        const roomPlayers = players.splice(0, Math.min(6, players.length));
        
        if (roomPlayers.length >= 2) {
          await createRoomFromMatchPool(roomPlayers, parseInt(difficulty));
        }
      }
    }

  } catch (error) {
    console.error("Error processing match pool:", error);
  }
}

async function createRoomFromMatchPool(players, difficulty) {
  try {
    const Room = Parse.Object.extend("Room");
    const room = new Room();
    
    room.set("difficulty", difficulty);
    room.set("status", "playing");
    room.set("unansweredCount", 0);
    room.set("maxPlayers", 6);
    
    // Add players to room
    const users = players.map(p => p.user);
    room.set("users", users);
    
    await room.save(null, { useMasterKey: true });

    // Remove players from match pool
    const playerEntries = players.map(p => p.entry);
    await Parse.Object.destroyAll(playerEntries, { useMasterKey: true });

    // Send push notifications to all players
    const pushQuery = new Parse.Query(Parse.Installation);
    pushQuery.containedIn("user", users);
    
    const usernames = players.map(p => p.username).join(", ");
    
    await Parse.Push.send({
      where: pushQuery,
      data: {
        alert: `游戏开始！房间 ${difficulty}星难度，玩家: ${usernames}`,
        sound: "default",
        roomId: room.id,
        type: "game_started"
      }
    }, { useMasterKey: true });

    console.log(`Created room ${room.id} with ${players.length} players, difficulty ${difficulty}`);
    
    return room;
    
  } catch (error) {
    console.error("Error creating room from match pool:", error);
    throw error;
  }
}

// 3) createShortCode - 生成4位随机码→存ShortLink→返回二维码海报URL
Parse.Cloud.define("createShortCode", async (request) => {
  const { roomId } = request.params;

  if (!roomId) {
    throw new Error('Room ID is required');
  }

  try {
    // Generate unique 4-character code
    let code;
    let attempts = 0;
    const maxAttempts = 10;

    do {
      code = generateShortCode();
      attempts++;
      
      if (attempts > maxAttempts) {
        throw new Error('Unable to generate unique short code');
      }
      
      // Check if code already exists
      const existingQuery = new Parse.Query("ShortLink");
      existingQuery.equalTo("code", code);
      const existing = await existingQuery.first({ useMasterKey: true });
      
      if (!existing) {
        break;
      }
    } while (true);

    // Create short link
    const ShortLink = Parse.Object.extend("ShortLink");
    const shortLink = new ShortLink();
    
    shortLink.set("code", code);
    shortLink.set("roomId", roomId);
    
    await shortLink.save(null, { useMasterKey: true });

    // Generate QR code poster URL
    const posterUrl = `https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=https://yourapp.com/join/${code}`;

    return {
      success: true,
      code: code,
      roomId: roomId,
      posterUrl: posterUrl,
      shareUrl: `https://yourapp.com/join/${code}`
    };

  } catch (error) {
    console.error("Error creating short code:", error);
    return {
      success: false,
      error: error.message
    };
  }
});

function generateShortCode() {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  let code = '';
  for (let i = 0; i < 4; i++) {
    code += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return code;
}

// 4) afterSave hooks for Question to call 阿里云内容安全审核
Parse.Cloud.afterSave("Question", async (request) => {
  const question = request.object;
  
  // Only run content moderation if question is new or content was modified
  if (request.original) {
    // Check if content fields were modified
    const original = request.original;
    const titleChanged = original.get("title") !== question.get("title");
    const optionsChanged = JSON.stringify(original.get("options")) !== JSON.stringify(question.get("options"));
    
    if (!titleChanged && !optionsChanged) {
      return;
    }
  }

  try {
    // Prepare content for moderation
    const contentToCheck = {
      title: question.get("title") || "",
      options: question.get("options") || []
    };

    // Call Aliyun content moderation service
    const moderationResult = await moderateContent(contentToCheck);
    
    // Update question with moderation status
    question.set("isAudited", moderationResult.passed);
    question.set("auditResult", moderationResult);
    question.set("auditedAt", new Date());
    
    await question.save(null, { useMasterKey: true });

    console.log(`Content moderation completed for question ${question.id}: ${moderationResult.passed ? 'PASSED' : 'FAILED'}`);
    
  } catch (error) {
    console.error("Error in content moderation:", error);
    
    // Mark as failed moderation on error
    question.set("isAudited", false);
    question.set("auditError", error.message);
    question.set("auditedAt", new Date());
    
    await question.save(null, { useMasterKey: true });
  }
});

// Aliyun content moderation service integration
async function moderateContent(content) {
  try {
    // This is a mock implementation
    // In real implementation, you would call Aliyun Content Moderation API
    // https://help.aliyun.com/document_detail/70292.html
    
    const textToCheck = [content.title, ...content.options].join(' ');
    
    // Simple keyword-based moderation (replace with actual API call)
    const sensitiveWords = ['暴力', '色情', '赌博', '政治', '毒品'];
    const containsSensitive = sensitiveWords.some(word => textToCheck.includes(word));
    
    return {
      passed: !containsSensitive,
      reason: containsSensitive ? 'Contains sensitive content' : null,
      confidence: containsSensitive ? 0.9 : 0.1,
      details: {
        textCheck: {
          passed: !containsSensitive,
          sensitiveWords: containsSensitive ? sensitiveWords.filter(word => textToCheck.includes(word)) : []
        }
      },
      auditedAt: new Date()
    };
    
  } catch (error) {
    console.error("Error calling content moderation API:", error);
    return {
      passed: false,
      reason: 'Moderation service error',
      error: error.message
    };
  }
}

// Helper functions for match pool management
Parse.Cloud.define("joinMatchPool", async (request) => {
  const { difficulty, username } = request.params;
  const user = request.user;

  if (!user || !difficulty || !username) {
    throw new Error('Missing required parameters');
  }

  try {
    // Check if user is already in match pool
    const existingQuery = new Parse.Query("MatchPool");
    existingQuery.equalTo("userId", user.id);
    const existing = await existingQuery.first({ useMasterKey: true });
    
    if (existing) {
      // Update existing entry
      existing.set("difficulty", difficulty);
      existing.set("username", username);
      existing.set("joinedAt", new Date());
      await existing.save(null, { useMasterKey: true });
      
      return { success: true, message: "Updated existing match pool entry" };
    }

    // Create new match pool entry
    const MatchPool = Parse.Object.extend("MatchPool");
    const matchPool = new MatchPool();
    
    matchPool.set("userId", user.id);
    matchPool.set("user", user);
    matchPool.set("username", username);
    matchPool.set("difficulty", difficulty);
    matchPool.set("joinedAt", new Date());
    
    await matchPool.save(null, { useMasterKey: true });

    return { success: true, message: "Joined match pool successfully" };

  } catch (error) {
    console.error("Error joining match pool:", error);
    return { success: false, error: error.message };
  }
});

Parse.Cloud.define("leaveMatchPool", async (request) => {
  const user = request.user;

  if (!user) {
    throw new Error('User not authenticated');
  }

  try {
    const matchPoolQuery = new Parse.Query("MatchPool");
    matchPoolQuery.equalTo("userId", user.id);
    const entry = await matchPoolQuery.first({ useMasterKey: true });
    
    if (entry) {
      await entry.destroy({ useMasterKey: true });
      return { success: true, message: "Left match pool successfully" };
    }

    return { success: false, message: "Not in match pool" };

  } catch (error) {
    console.error("Error leaving match pool:", error);
    return { success: false, error: error.message };
  }
});

// Cloud Job: matchPoolCron - Process match pool every 1 second
Parse.Cloud.job("matchPoolCron", async (request) => {
  const { params, master, user } = request;
  const startTime = new Date();
  let roomsCreated = 0;
  let playersMatched = 0;
  
  try {
    console.log("Starting match pool processing at:", startTime);
    
    // Get all players in match pool grouped by difficulty
    const matchPoolQuery = new Parse.Query("MatchPool");
    const matchPoolEntries = await matchPoolQuery.find({ useMasterKey: true });
    
    if (matchPoolEntries.length === 0) {
      console.log("No players in match pool");
      return {
        success: true,
        message: "No players to match",
        playersProcessed: 0,
        roomsCreated: 0,
        executionTime: new Date() - startTime
      };
    }

    // Group by difficulty
    const playersByDifficulty = {};
    
    for (const entry of matchPoolEntries) {
      const difficulty = entry.get("difficulty") || 1;
      const userId = entry.get("userId");
      
      if (!playersByDifficulty[difficulty]) {
        playersByDifficulty[difficulty] = [];
      }
      
      // Check if user is not already in a room
      const userRoomQuery = new Parse.Query("Room");
      userRoomQuery.equalTo("users", entry.get("user"));
      const existingRoom = await userRoomQuery.first({ useMasterKey: true });
      
      if (!existingRoom) {
        playersByDifficulty[difficulty].push({
          entry: entry,
          user: entry.get("user"),
          username: entry.get("username"),
          userId: userId,
          difficulty: difficulty
        });
      }
    }

    // Process each difficulty level
    for (const difficulty in playersByDifficulty) {
      const players = playersByDifficulty[difficulty];
      
      console.log(`Processing ${players.length} players for difficulty ${difficulty}`);
      
      // Group players into rooms of max 6 (minimum 2 to start)
      while (players.length >= 2) {
        const roomPlayers = players.splice(0, Math.min(6, players.length));
        
        if (roomPlayers.length >= 2) {
          const room = await createRoomFromMatchPool(roomPlayers, parseInt(difficulty));
          if (room) {
            roomsCreated++;
            playersMatched += roomPlayers.length;
            console.log(`Created room ${room.id} with ${roomPlayers.length} players`);
          }
        }
      }
    }

    const executionTime = new Date() - startTime;
    
    console.log(`Match pool processing completed in ${executionTime}ms`);
    console.log(`Rooms created: ${roomsCreated}, Players matched: ${playersMatched}`);
    
    return {
      success: true,
      message: "Match pool processed successfully",
      playersProcessed: playersMatched,
      roomsCreated: roomsCreated,
      executionTime: executionTime,
      timestamp: new Date()
    };

  } catch (error) {
    console.error("Error in matchPoolCron job:", error);
    
    return {
      success: false,
      error: error.message,
      playersProcessed: 0,
      roomsCreated: 0,
      executionTime: new Date() - startTime,
      timestamp: new Date()
    };
  }
});

// Helper function to create room from match pool
async function createRoomFromMatchPool(players, difficulty) {
  try {
    const Room = Parse.Object.extend("Room");
    const room = new Room();
    
    room.set("difficulty", difficulty);
    room.set("status", "playing");
    room.set("unansweredCount", 0);
    room.set("maxPlayers", 6);
    
    // Add players to room
    const users = players.map(p => p.user);
    room.set("users", users);
    
    await room.save(null, { useMasterKey: true });

    // Remove players from match pool
    const playerEntries = players.map(p => p.entry);
    await Parse.Object.destroyAll(playerEntries, { useMasterKey: true });

    // Send push notifications to all players
    const pushQuery = new Parse.Query(Parse.Installation);
    pushQuery.containedIn("user", users);
    
    const usernames = players.map(p => p.username).join(", ");
    
    await Parse.Push.send({
      where: pushQuery,
      data: {
        alert: `🎮 游戏开始！${difficulty}星难度房间，玩家: ${usernames}`,
        sound: "default",
        roomId: room.id,
        type: "game_started",
        difficulty: difficulty,
        playerCount: players.length
      }
    }, { useMasterKey: true });

    // Post system chat message
    const AudienceChat = Parse.Object.extend("AudienceChat");
    const systemChat = new AudienceChat();
    systemChat.set("roomId", room.id);
    systemChat.set("username", "系统");
    systemChat.set("text", `🎉 房间创建成功！${difficulty}星难度，${players.length}位玩家加入游戏`);
    systemChat.set("ts", Date.now());
    await systemChat.save(null, { useMasterKey: true });

    console.log(`Room ${room.id} created successfully`);
    return room;
    
  } catch (error) {
    console.error("Error creating room from match pool:", error);
    throw error;
  }
}

// Clean up old match pool entries (older than 5 minutes)
Parse.Cloud.job("cleanupMatchPool", async (request) => {
  const startTime = new Date();
  
  try {
    const fiveMinutesAgo = new Date(startTime.getTime() - 5 * 60 * 1000);
    
    const oldEntriesQuery = new Parse.Query("MatchPool");
    oldEntriesQuery.lessThan("joinedAt", fiveMinutesAgo);
    const oldEntries = await oldEntriesQuery.find({ useMasterKey: true });
    
    if (oldEntries.length > 0) {
      await Parse.Object.destroyAll(oldEntries, { useMasterKey: true });
      console.log(`Cleaned up ${oldEntries.length} old match pool entries`);
    }
    
    return {
      success: true,
      message: `Cleaned up ${oldEntries.length} old entries`,
      entriesRemoved: oldEntries.length,
      executionTime: new Date() - startTime
    };
    
  } catch (error) {
    console.error("Error in cleanupMatchPool job:", error);
    return {
      success: false,
      error: error.message,
      entriesRemoved: 0,
      executionTime: new Date() - startTime
    };
  }
});

// Get match pool statistics
Parse.Cloud.define("getMatchPoolStats", async (request) => {
  try {
    const matchPoolQuery = new Parse.Query("MatchPool");
    const totalPlayers = await matchPoolQuery.count({ useMasterKey: true });
    
    const pipeline = [
      {
        group: {
          objectId: "$difficulty",
          difficulty: { $max: "$difficulty" },
          count: { $sum: 1 }
        }
      }
    ];
    
    const difficultyStats = await matchPoolQuery.aggregate(pipeline, { useMasterKey: true });
    
    return {
      success: true,
      totalPlayers: totalPlayers,
      byDifficulty: difficultyStats,
      timestamp: new Date()
    };
    
  } catch (error) {
    console.error("Error getting match pool stats:", error);
    return {
      success: false,
      error: error.message
    };
  }
});

// Health check function
Parse.Cloud.define("healthCheck", async (request) => {
  return {
    success: true,
    timestamp: new Date(),
    version: "1.0.0",
    matchPoolRunning: matchPoolInterval !== null
  };
});